package com.lagou.handler;

import com.lagou.RpcRequest;
import com.lagou.RpcResponse;
import com.lagou.boot.AppContext;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;

/**
 * 自定义的业务处理器
 */
public class RpcHandler extends ChannelInboundHandlerAdapter {

    //当客户端读取数据时,该方法会被调用
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof RpcRequest) {
            try {
                RpcRequest rpcRequest = (RpcRequest) msg;

                // 需要调用的类或对应的接口
                String className = rpcRequest.getClassName();
                Class<?> aClass = Class.forName(className);

                // 容器中找到对应的Bean
                Object bean = AppContext.getBean(aClass);

                // 需要调用的方法名
                String methodName = rpcRequest.getMethodName();
                // 需要调用的方法参数类型
                Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
                // 调用方法的参数
                Object[] parameters = rpcRequest.getParameters();

                // 获取到需要执行的方法
                Method method = aClass.getMethod(methodName, parameterTypes);

                // 反射调用方法
                Object res = method.invoke(bean, parameters);

                // 结果封装到RpcResponse
                RpcResponse rpcResponse = new RpcResponse();
                rpcResponse.setResponseId(rpcRequest.getRequestId());
                rpcResponse.setObj(res);

                // 想通道写入对象，交给序列化等链路处理
                ctx.writeAndFlush(rpcResponse);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
